package jwts

import (
	"errors"
	"github.com/golang-jwt/jwt/v4"
	"time"
)

type MyClaims struct {
	ID                   int
	Username             string
	IP                   string
	jwt.RegisteredClaims // 注意!这是jwt-go的v4版本新增的，原先是jwt.StandardClaims
}

var secret = []byte("kldjgphjiodjudtyj12345.") // 定义secret，后面会用到

// Encrypt 生成token
func Encrypt(id int, username, ip string, s int) (tokenString string, time2 time.Time, err error) {
	ExpiresAt := time.Now().Add(time.Duration(s) * time.Hour * time.Duration(1)) // 过期时间 小时
	//ExpiresAt := time.Now().Add(time.Duration(s) * time.Second * time.Duration(1)) // 过期时间 小时
	claim := MyClaims{
		ID:       id,
		Username: username,
		IP:       ip,
		RegisteredClaims: jwt.RegisteredClaims{
			ExpiresAt: jwt.NewNumericDate(ExpiresAt),
			IssuedAt:  jwt.NewNumericDate(time.Now()), // 签发时间
			NotBefore: jwt.NewNumericDate(time.Now()), // 生效时间
		}}
	token := jwt.NewWithClaims(jwt.SigningMethodHS256, claim) // 使用HS256算法
	tokenString, err = token.SignedString(secret)
	return tokenString, ExpiresAt, err
}

func Secret() jwt.Keyfunc {
	return func(token *jwt.Token) (interface{}, error) {
		return secret, nil // 这是我的secret
	}
}

// Decrypt 解析token
func Decrypt(tokenss string) (*MyClaims, error) {
	token, err := jwt.ParseWithClaims(tokenss, &MyClaims{}, Secret())
	if err != nil {
		var ve *jwt.ValidationError
		if errors.As(err, &ve) {
			if ve.Errors&jwt.ValidationErrorMalformed != 0 {
				return nil, errors.New("token 格式错误")
			} else if ve.Errors&jwt.ValidationErrorExpired != 0 {
				return nil, errors.New("token 已过期")
			} else if ve.Errors&jwt.ValidationErrorNotValidYet != 0 {
				return nil, errors.New("token 未激活")
			} else {
				return nil, errors.New("无法处理此 token")
			}
		}
	}
	if claims, ok := token.Claims.(*MyClaims); ok && token.Valid {
		return claims, nil
	}
	return nil, errors.New("无法处理此 token")
}
